<script setup>
import { ref, computed, watch } from 'vue';
import ComboboxOption from './ComboboxOption.vue';
import { useCombobox } from './useCombobox';

const props = defineProps({
  modelValue: [String, Number, Object],
  options: {
    type: Array,
    default: () => []
  },
  placeholder: String,
  valueKey: {
    type: String,
    default: 'value'
  },
  labelKey: {
    type: String,
    default: 'label'
  },
  disabled: Boolean,
  clearable: Boolean,
  loading: Boolean,
  noOptionsText: {
    type: String,
    default: '无匹配结果'
  }
});

const emit = defineEmits(['update:modelValue', 'change', 'search']);

// 使用组合式API
const {
  inputRef,
  isOpen,
  selectedIndex,
  searchValue,
  filteredOptions,
  displayValue,
  toggleDropdown,
  openDropdown,
  closeDropdown,
  handleInput,
  selectOption,
  handleKeyDown,
  scrollToSelected,
  clearSearch
} = useCombobox(props, emit);

// 清空选择
const clearSelection = () => {
  emit('update:modelValue', null);
  searchValue.value = '';
};

// 显示清空按钮
const showClear = computed(() => {
  return props.clearable && props.modelValue !== null && props.modelValue !== '';
});

// 加载状态图标
const displayIcon = computed(() => {
  if (props.loading) return '⏳';
  if (isOpen.value) return '▲';
  return '▼';
});
</script>

<template>
  <div class="combobox" :class="{ 'disabled': disabled }">
    <div class="combobox-input">
      <input
          ref="inputRef"
          type="text"
          :value="displayValue"
          :placeholder="placeholder"
          @input="handleInput"
          @focus="openDropdown"
          @keydown="handleKeyDown"
          :disabled="disabled"
      />

      <!-- 清空按钮 -->
      <button
          v-if="showClear"
          class="clear-button"
          @click.stop="clearSelection"
          :disabled="disabled"
      >
        ✕
      </button>

      <!-- 加载状态/下拉图标 -->
      <button
          class="dropdown-button"
          @click.stop="toggleDropdown"
          :disabled="disabled"
      >
        {{ displayIcon }}
      </button>
    </div>

    <div v-show="isOpen" class="dropdown-menu">
      <ul v-if="filteredOptions.length > 0">
        <combobox-option
            v-for="(option, index) in filteredOptions"
            :key="option[valueKey] || index"
            :option="option"
            :value-key="valueKey"
            :label-key="labelKey"
            :is-selected="index === selectedIndex"
            @select="selectOption"
        >
          <slot name="option" v-bind="{ option }">
            {{ option[labelKey] }}
          </slot>
        </combobox-option>
      </ul>

      <div v-else class="no-options">
        {{ noOptionsText }}
      </div>
    </div>
  </div>
</template>

<style scoped>
.combobox {
  position: relative;
  width: 100%;
}

.combobox.disabled {
  opacity: 0.6;
  pointer-events: none;
}

.combobox-input {
  position: relative;
  display: flex;
  align-items: center;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  background: white;
}

.combobox-input input {
  width: 100%;
  padding: 9px 12px;
  border: none;
  background: transparent;
  font-size: 14px;
}

.combobox-input input:focus {
  outline: none;
}

.combobox-input:focus-within {
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

.dropdown-button,
.clear-button {
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  padding: 0 8px;
  color: #c0c4cc;
  cursor: pointer;
}

.clear-button {
  font-size: 16px;
  line-height: 1;
}

.clear-button:hover {
  color: #409eff;
}

.dropdown-menu {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  max-height: 200px;
  overflow-y: auto;
  margin-top: 4px;
  background: white;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  z-index: 100;
}

.dropdown-menu ul {
  list-style: none;
  padding: 6px 0;
  margin: 0;
}

.no-options {
  padding: 12px;
  text-align: center;
  color: #909399;
  font-size: 14px;
}
</style>